//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name: wbtshell.cpp

Abstract:

Notes:
--*/


#include <windows.h>
#include "wbtshell.h"
#include "wbtstart.h"
#include "wbtdsktp.h"
#include "wbttskbr.h"
//#include "dst.h"

#ifdef DEBUG
#include <debug.h>

DBGPARAM dpCurSettings = {
  TEXT("WBTSHELL"), {
  TEXT("ERROR"),TEXT("WARNING"),TEXT("INFO"),TEXT("TRACE"),
  TEXT("TRACEV"),TEXT("NOTIFY"),TEXT("EVENT"),TEXT("MSG"),
  TEXT(""),TEXT(""),TEXT(""),TEXT(""),
  TEXT(""),TEXT(""),TEXT(""),TEXT("") },
  0x0000001F
};

#endif

#define STORE_SIZE_SHARE	20

const LPWSTR szRegKeyShellSettings = TEXT("Software\\Microsoft\\WBT\\Shell");
const LPWSTR szTaskmanExe = TEXT("taskman.exe");
HINSTANCE g_hInstance;

DWORD WINAPI StartupProc(LPVOID lpvThreadParam);
DWORD WINAPI TaskmanProc(LPVOID lpvThreadParam);
VOID  WINAPI StartProcess(PSTARTUP_DATA sdata);
VOID  WINAPI Startup();

/*++

--*/
INT WINAPI
WinMain (
   HINSTANCE hInstance,
   HINSTANCE hPrevInstance,
   LPWSTR szCmdLine,
   INT iCmdShow
   ) {
 
   PWBTTASKBAR ptb;
   PWBTDESKTOP pdt;
   DWORD dwThrdId;
   HANDLE hThrd;
   MSG msg;      
      
   //====================AAS==============================
   HANDLE hnd = LoadLibrary(TEXT("wificpl.cpl"));
   //====================AAS==============================

   g_hInstance = hInstance;
   ZEROVAR(msg);

   if (FindWindow(szDesktopWndClassName, NULL)) {
      DEBUGMSG(ZONE_ERROR,
              (TEXT("Desktop window is already running.\r\n")));
      return -1;
      }

	DWORD dwPageSize, dwStorePages, dwRamPages;
	GetSystemMemoryDivision(&dwStorePages, &dwRamPages, &dwPageSize);
	dwStorePages = (DWORD)((STORE_SIZE_SHARE/100.0) * (dwStorePages+dwRamPages));
	if (SYSMEM_CHANGED != SetSystemMemoryDivision (dwStorePages))
		DEBUGMSG(ZONE_ERROR,(TEXT("Failed to set the system memory division.\r\n")));
             
   pdt = new WBTDESKTOP;
   if ((!pdt) || (!pdt->InitInstance(hInstance))) {
         return -1;
      }

   ptb = new WBTTASKBAR;
   if ((!ptb) || (!ptb->InitInstance(hInstance))) {
         delete pdt;
         return -1;
      }
   
   if(!RegisterTaskBar(FindWindow(szTaskbarWndClassName, NULL))) {
      RETAILMSG(1,(TEXT("RegisterTaskBar failed!\r\n")));
      delete ptb;
      delete pdt;
      return -1;
      }
   
   hThrd =
      CreateThread(
         NULL,
         0,
         (LPTHREAD_START_ROUTINE)StartupProc,
         (LPVOID)NULL,
         0,
         &dwThrdId
         );

   if (!hThrd) {
      RETAILMSG(1,(TEXT("WBTSHELL: Startup thread failed to start! (%d)\r\n"), GetLastError));
      }
   else
	   CloseHandle(hThrd);

/*
    hThrd = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) DST_Init, NULL, 0, NULL);
    if (hThrd)
        CloseHandle(hThrd);
*/

   while (GetMessage(&msg, NULL, 0, 0)) {               
         TranslateMessage(&msg);
         DispatchMessage(&msg);
         }
   
   delete ptb;
   delete pdt;
   return msg.wParam;
}


/*++

--*/


DWORD WINAPI
StartupProc(LPVOID lpvThreadParam) {
   
   DWORD dwThrdId;
   HANDLE hThrd;

   DEBUGMSG(ZONE_TRACE,(TEXT("WBTSHELL: StartupProc thread entered.\r\n")));
   Startup();          
   
   hThrd =
      CreateThread(
         NULL,
         0,
         (LPTHREAD_START_ROUTINE)TaskmanProc,
         (LPVOID)NULL,
         0,
         &dwThrdId
         );

   if (!hThrd) {
      RETAILMSG(1,(TEXT("WBTSHELL: Startup thread failed to start! (%d)\r\n"), GetLastError));
   }   
   else
	   CloseHandle(hThrd);

   
   DEBUGMSG(ZONE_TRACE,(TEXT("WBTSHELL: StartupProc thread exit.\r\n")));   
   ExitThread(0);
   return 0;
}

/*++

--*/


DWORD WINAPI
TaskmanProc(LPVOID lpvThreadParam) {

   INT iCnt;
   BOOL bResult;
   TCHAR szCmdLine[20];
   PROCESS_INFORMATION pi;   
   HWND hwndDesktop = FindWindow(szDesktopWndClassName, NULL);


   DEBUGMSG(ZONE_TRACE,(TEXT("WBTSHELL: TaskmanProc thread entered.\r\n")));
   
   if (!hwndDesktop) {
      DEBUGMSG(ZONE_ERROR,(TEXT("WBTSHELL: can't find Desktop window!!!\r\n")));
      goto EXIT_TASKMAN_PROC;
      }


   iCnt = 0;
   szCmdLine[0] = NULL;

   while(1) {
      
      if (FindWindow(szTaskmanWndClassName, NULL)) {
         RETAILMSG(1,(TEXT("WBTSHELL: Error in TaskmanProc. $s already running!\r\n"), szTaskmanWndClassName));
         goto EXIT_TASKMAN_PROC;
         }
      
      SendMessage(hwndDesktop, WBTSHL_SETCURSOR, 0, CURSOR_APPSTRT);   
      bResult = 
         CreateProcess(
            szTaskmanExe,
            szCmdLine,
            NULL,
            NULL,
            FALSE,
            NULL,
            NULL,
            NULL,
            NULL,
            &pi
            );
      SendMessage(hwndDesktop, WBTSHL_SETCURSOR, 0, CURSOR_ARROW);

      if (!bResult) {
         CreateProcessError(g_hInstance, NULL, szTaskmanExe, GetLastError());
         goto EXIT_TASKMAN_PROC;
         }
         
      WaitForSingleObject(pi.hProcess, INFINITE);
      wsprintf(szCmdLine, TEXT("%d"), ++iCnt);
      RETAILMSG(1,(TEXT("WBTSHELL: Taskman died! Restarting...\r\n")));

   }

EXIT_TASKMAN_PROC:

   DEBUGMSG(ZONE_TRACE,(TEXT("WBTSHELL: TaskmanProc thread exit.\r\n")));
   ExitThread(0);
   return 0;
}


/*++

--*/

VOID
Startup() {

   INT index;
   PSTARTUP_DATA sdata;
   PSTARTUP_LIST startup = new STARTUP_LIST;
   
   if (!startup)
	   return;

   startup->InitInstance();

#ifdef DEBUG
   startup->DbgDumpStartupList();
#endif
   
   for (index = 0; index < startup->GetCount(); index++) {
      if(startup->GetDataByIndex(index, sdata)) {                  
         StartProcess(sdata);
         }
      }

   delete startup;
}


/*++

--*/

VOID
StartProcess(PSTARTUP_DATA sdata) {
   
   BOOL bResult;
   PROCESS_INFORMATION pi;   
   HWND hwndDesktop = FindWindow(szDesktopWndClassName, NULL);

   if (!hwndDesktop) {
      DEBUGMSG(ZONE_ERROR,(TEXT("Error: StartProcess cannot find hwndDesktop!!!\r\n")));
      return;
      }
   
   DEBUGMSG(ZONE_TRACE,(TEXT("\nWBTSHELL: launching autostart entry 0x%08x:\r\n"), sdata->nIndex));
   DEBUGMSG(ZONE_TRACE,(TEXT("  > Appliaction: \"%s\"\r\n"), sdata->szApplication));
   DEBUGMSG(ZONE_TRACE,(TEXT("  > CmdLine: \"%s\"\r\n"), sdata->szCmdLine));
   DEBUGMSG(ZONE_TRACE,(TEXT("  > WaitFlag: 0x%08x\r\n\n"), sdata->dwWaitFlag));
      
   SendMessage(hwndDesktop, WBTSHL_SETCURSOR, 0, CURSOR_APPSTRT);   
   bResult = 
      CreateProcess(
          sdata->szApplication,
          sdata->szCmdLine,
          NULL,
          NULL,
          FALSE,
          NULL,
          NULL,
          NULL,
          NULL,
          &pi
          );
   SendMessage(hwndDesktop, WBTSHL_SETCURSOR, 0, CURSOR_ARROW);

   if (!bResult) {
      CreateProcessError(g_hInstance, NULL, sdata->szApplication, GetLastError());
      return;
      }
   
   if (sdata->dwWaitFlag) {
      WaitForSingleObject(pi.hProcess, INFINITE);
      }
}



